//package org.batatasframework.web.method.resolver;
//
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//
//import org.batatasframework.web.annotations.TemplateDatagrid;
//import org.batatasframework.web.annotations.TemplateDetail;
//import org.batatasframework.web.annotations.TemplateEditor;
//import org.batatasframework.web.annotations.TemplateTreegrid;
//import org.batatasframework.web.template.TemplateBlock;
//import org.batatasframework.web.template.TemplateManager;
//import org.batatasframework.web.template.spi.TemplateGenerator;
//import org.batatasframework.web.template.spi.TemplateType;
//import org.springframework.core.MethodParameter;
//import org.springframework.web.bind.support.WebDataBinderFactory;
//import org.springframework.web.context.request.NativeWebRequest;
//import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
//import org.springframework.web.method.support.ModelAndViewContainer;
//
//public class TemplateArgumentResolver extends AbstractArgumentResolver implements HandlerMethodReturnValueHandler{
//	
//	private TemplateManager templateManager;
//
//	private Map<MethodParameter, TemplateBlock> mapped = new ConcurrentHashMap<>(64);
//	
//	private final InternalTemplateParser[] parsers = {
//		new InternalTemplateParser(){
//
//			@Override
//			public boolean parse(InternalTemplateGenerator generator, MethodParameter parameter) {
//				TemplateDatagrid temp = parameter.getParameterAnnotation(TemplateDatagrid.class);
//				if(null == temp){ return false; }
//				
//				generator.setBlock(templateManager.parse(TemplateType.DATAGRID, temp.value()));
//				
//				return true;
//			}
//			
//		},
//		new InternalTemplateParser(){
//
//			@Override
//			public boolean parse(InternalTemplateGenerator generator, MethodParameter parameter) {
//				TemplateEditor temp = parameter.getParameterAnnotation(TemplateEditor.class);
//				if(null == temp){ return false; }
//				
//				generator.setBlock(templateManager.parse(TemplateType.EDITOR, temp.value()));
//				
//				return true;
//			}
//		},
//		new InternalTemplateParser(){
//
//			@Override
//			public boolean parse(InternalTemplateGenerator generator, MethodParameter parameter) {
//				TemplateTreegrid temp = parameter.getParameterAnnotation(TemplateTreegrid.class);
//				if(null == temp){ return false; }
//				
//				generator.setBlock(templateManager.parse(TemplateType.TREEGRID, temp.value()));
//				
//				return true;
//			}
//		},
//		new InternalTemplateParser(){
//
//			@Override
//			public boolean parse(InternalTemplateGenerator generator, MethodParameter parameter) {
//				TemplateDetail temp = parameter.getParameterAnnotation(TemplateDetail.class);
//				if(null == temp){ return false; }
//				
//				generator.setBlock(templateManager.parse(TemplateType.DETAIL, temp.value()));
//				
//				return true;
//			}
//		}
//	};
//
//	@Override
//	public void afterPropertiesSet() throws Exception {
//		templateManager = beanFactory.getBean(TemplateManager.class);
//	}
//
//	@Override
//	public boolean supportsParameter(MethodParameter parameter) {
//		Class<?> paramType = parameter.getParameterType();
//		return TemplateGenerator.class.isAssignableFrom(paramType);
//	}
//
//	@Override
//	public boolean supportsReturnType(MethodParameter returnType) {
//		Class<?> paramType = returnType.getParameterType();
//		return TemplateGenerator.class.isAssignableFrom(paramType);
//	}
//
//	@Override
//	public void handleReturnValue(Object returnValue,
//			MethodParameter returnType, ModelAndViewContainer mavContainer,
//			NativeWebRequest webRequest) throws Exception {
//		
//		if(returnValue instanceof TemplateGenerator){
//			TemplateGenerator generator = (TemplateGenerator)returnValue;
//			mavContainer.setViewName(generator.getViewName());
//		}
//	}
//	
//	@Override
//	public Object resolveArgument(MethodParameter parameter,
//			ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
//			WebDataBinderFactory binderFactory) throws Exception {
//
//		InternalTemplateGenerator generator = new InternalTemplateGenerator();
//		TemplateBlock block = mapped.get(parameter);
//		
//		if(null != block){
//			generator.setBlock(block);
//			return generator.finish(mavContainer, binderFactory);
//		}
//				
//		for(InternalTemplateParser parser : parsers){
//			if(parser.parse(generator, parameter)) {
//				mapped.put(parameter, generator.block);
//				return generator.finish(mavContainer, binderFactory);
//			}
//		}
//
//		return unsupported(parameter);
//	}
//
//	private interface InternalTemplateParser{
//		boolean parse(InternalTemplateGenerator generator, MethodParameter parameter);
//	}
//	
//	private class InternalTemplateGenerator implements TemplateGenerator{
//		private TemplateBlock block;
//		public void setBlock(TemplateBlock block) {
//			this.block = block;
//		}
//		
//		public TemplateGenerator finish(ModelAndViewContainer mavContainer, WebDataBinderFactory binderFactory){
//
//			return this;
//		}
//
//		@Override
//		public String getViewName() {
//			return block.getViewName();
//		}
//	}
//}
